Examine the Custom_component example to see how custom controls are implemented. The example includes a Custom_component_toolmodule configuration, which you can use to generate a toolmodule plugin (.dll). By adding this preview module into your application configuration in Kanzi Studio, you can see the behavior of your custom control in the Preview. Kanzi Studio also imports all properties and message types that are defined in the registerToFactory implementation, so you can use them in Kanzi Studio similarly to any other components and message types.
To create a custom control:
const KzuFactoryObjectTypeIdentifier = OBJECT_TYPE_MYCONTROL
KzuUiComponentNodeClass for your custom control. Often, implementing your custom initialize and uninitialize functions is sufficient and you can use the default implementations for everything else.
const struct KzuUiComponentNodeClass CUSTOM_MYCONTROL_CLASS =
{
{
&KZU_UI_COMPONENT_NODE_CLASS,
myControlInitialize,
myControlUninitialize,
kzuObjectNodeOnAttached_protected,
kzuObjectNodeOnDetached_protected,
kzuUiComponentNodeCopy_protected,
kzuUiComponentNodeRender_protected,
kzuUiComponentNodeGetBoundingVolume_protected
},
kzuUiComponentNodeMeasure_protected,
kzuUiComponentNodeArrange_protected,
kzuUiComponentNodeValidateRender_protected,
kzuUiComponentNodeCopyComponent_protected
};
myControlInitialize and myControlUninitialize. Override OnAttached and OnDetached instead, if the logic is dependent on the object’s existence in the scene graph hierarchy.registerToFactory function, which registers the object type FACTORY_OBJECT_TYPE_MYCONTROL, as well as any custom properties and message types that are generated or used by the control. registerToFactory implementation in your application’s kzApplicationConfigure implementation.The following code shows simple initialize and uninitialized behavior where the custom control only registers and deregisters a message handler for a custom message type:
KZ_CALLBACK static kzsError myControlInitialize(struct KzuObjectNode* objectNode)
{
struct KzuUiComponentNode* componentNode =
kzuUiComponentNodeFromObjectNode(objectNode);
struct MyControl* myControl =
myControlFromUiComponentNode(componentNode);
struct KzuMessageDispatcher* messageDispatcher =
kzuObjectNodeGetMessageDispatcher(objectNode);
/* Initialize parent class. */
kzuUiComponentNodeInitialize_private(objectNode);
/* Add a message handler for myCustomMessages for the myControl object node. We
* define object-source as KZ_NULL, so that all myCustomMessages that originate
* from myControl's children will be intercepted. */
kzuMessageDispatcherAddHandler(messageDispatcher, objectNode,
MESSAGE_MY_CUSTOM_MESSAGE, KZ_NULL, myCustomMessageHandler, myControl);
kzsSuccess();
}
KZ_CALLBACK static kzsError myControlUninitialize(struct KzuObjectNode* objectNode)
{
struct KzuUiComponentNode* componentNode =
kzuUiComponentNodeFromObjectNode(objectNode);
struct MyControl* myControl =
myControlFromUiComponentNode(componentNode);
struct KzuMessageDispatcher* messageDispatcher =
kzuObjectNodeGetMessageDispatcher(objectNode);
/* Remove the message handler that was created for the custom component. */
kzuMessageDispatcherRemoveHandler(messageDispatcher, objectNode,
MESSAGE_MY_CUSTOM_MESSAGE, myCustomMessageHandler, myControl);
/* Uninitialize parent class. */
kzuUiComponentNodeUninitialize_private(objectNode);
kzsSuccess();
}